package p3.cse;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.DropboxFileInfo;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.exception.DropboxUnlinkedException;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.Session.AccessType;

/**
 * This activity uses the Dropbox API to backup the local password database to a
 * user's private storage online.
 */
public final class Backup extends Activity {
	/**
	 * Public key identifying this application to Dropbox.
	 */
	private static final String APP_KEY = "nj86squt0xlrcy2";

	/**
	 * Private secret for authenticating this application with Dropbox.
	 */
	private static final String APP_SECRET = "s18hi9etgg1hbzb";

	/**
	 * Identifies access to Dropbox as restricted to a single application
	 * folder, rather than the entire Dropbox storage.
	 */
	private static final AccessType ACCESS_TYPE = AccessType.APP_FOLDER;

	/**
	 * TODO: There should be a better way of passing this information.
	 */
	public static boolean downloading = false;

	/**
	 * Storage for the Dropbox session information.
	 */
	private DropboxAPI<AndroidAuthSession> mDBApi;

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.d("upload", "started onCreate");
		AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
		AndroidAuthSession session = new AndroidAuthSession(appKeys,
				ACCESS_TYPE);
		mDBApi = new DropboxAPI<AndroidAuthSession>(session);

		// MyActivity below should be your activity class name
		mDBApi.getSession().startAuthentication(Backup.this);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void onResume() {
		super.onResume();

		if (mDBApi.getSession().authenticationSuccessful()) {
			try {
				// MANDATORY call to complete auth.
				// Sets the access token on the session
				mDBApi.getSession().finishAuthentication();
				AccessTokenPair tokens = mDBApi.getSession()
						.getAccessTokenPair();
				if (downloading) {
					download(tokens);
					Intent restart = new Intent(Backup.this, Unlock.class);
					startActivity(restart);
					finish();
				} else {
					upload(tokens);
					finish();
				}
			} catch (IllegalStateException e) {
				Log.i("DbAuthLog", "Error authenticating", e);
			}
		}
		
	}

	/**
	 * Uses the Dropbox API to upload the password database.
	 * 
	 * @param tokens
	 *            the currently logged in user's access token and secret.
	 */
	public void upload(final AccessTokenPair tokens) {
		mDBApi.getSession().setAccessTokenPair(tokens);

		FileInputStream inputStream = null;
		try {
			inputStream = new FileInputStream(Filer.DB_FILE);
			DropboxAPI.Entry newEntry = mDBApi.putFileOverwrite(
					Filer.DB_FILE.getName(), inputStream,
					Filer.DB_FILE.length(), null);
			Log.i("DbExampleLog", "The uploaded file's rev is: " + newEntry.rev);
		} catch (DropboxUnlinkedException e) {
			// User has unlinked, ask them to link again here.
			Log.e("DbExampleLog", "User has unlinked.");
		} catch (DropboxException e) {
			Log.e("DbExampleLog", "Something went wrong while uploading.");
		} catch (FileNotFoundException e) {
			Log.e("DbExampleLog", "File not found.");
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					Log.e("DbExampleLog", "Problem closing file.");
				}
			}
		}
	}

	/**
	 * Uses the Dropbox API to download the password database.
	 * 
	 * @param tokens
	 *            the currently logged in user's access token and secret.
	 */
	public void download(final AccessTokenPair tokens) {
		mDBApi.getSession().setAccessTokenPair(tokens);

		FileOutputStream outputStream = null;
		try {
			outputStream = new FileOutputStream(Filer.DB_FILE);
			DropboxFileInfo info = mDBApi.getFile(Filer.DB_FILE.getName(),
					null, outputStream, null);
			Log.i("DbExampleLog", "The file's rev is: "
					+ info.getMetadata().rev);
			// /path/to/new/file.txt now has stuff in it.
		} catch (DropboxException e) {
			Log.e("DbExampleLog", "Something went wrong while downloading.");
		} catch (FileNotFoundException e) {
			Log.e("DbExampleLog", "File not found.");
		} finally {
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e) {
					Log.e("DbExampleLog", "Problem closing file.");
				}
			}
		}

	}
}
